package org.coody.framework.minicat.entity;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.text.MessageFormat;
import java.util.HashMap;

import org.coody.framework.minicat.config.MiniCatConfig;
import org.coody.framework.minicat.util.GZIPUtils;
import org.coody.framework.minicat.util.StringUtil;

public class MinitCatHttpInstance {

	private Socket socket;

	private HttpServletRequest request;

	private HttpServletResponse response;

	public MinitCatHttpInstance(Socket socket) throws IOException {
		this.socket = socket;
		this.response = new HttpServletResponse();
	}

	public void buildRequest() throws IOException {
		this.request = new HttpServletRequest(socket);
	}

	public Socket getSocket() {
		return socket;
	}

	public void setSocket(Socket socket) {
		this.socket = socket;
	}

	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public HttpServletResponse getResponse() {
		return response;
	}

	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}

	public void flushAndClose() {
		try {
			socket.getOutputStream().write(response.getOutputStream().toByteArray());
			socket.getOutputStream().flush();
			socket.getOutputStream().close();
			response.getOutputStream().close();
		} catch (Exception e) {
		} finally {
			if (request != null && request.getInputStream() != null) {
				try {
					request.getInputStream().close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (socket != null && !socket.isClosed()) {
				try {
					if (socket.getOutputStream() != null) {
						socket.getOutputStream().close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public ByteArrayOutputStream buildResponse(byte[] data) throws IOException {
		return buildResponse(response.getHttpCode(), data);
	}

	public ByteArrayOutputStream buildResponse(int httpCode, String msg) throws IOException {
		return buildResponse(httpCode, msg.getBytes(MiniCatConfig.ENCODE));
	}

	public ByteArrayOutputStream buildResponse(int httpCode, byte[] data) throws IOException {
		if (StringUtil.isNullOrEmpty(response.getHeader())) {
			response.setHeader(new HashMap<String, String>());
		}

		response.getHeader().put("Connection", "close");
		response.getHeader().put("Server", "MiniCat/1.0 By Coody");
		if (!response.getHeader().containsKey("Content-Type")) {
			response.getHeader().put("Content-Type", "text/html");
		}
		if (MiniCatConfig.OPENGZIP) {
			response.getHeader().put("Content-Encoding", "gzip");
			// 压缩数据
			data = GZIPUtils.compress(data);
		}
		response.getHeader().put("Content-Length", data==null?"0":String.valueOf(data.length));
		if (request != null && request.isSessionCread()) {
			String cookie = MessageFormat.format("{0}={1}; HttpOnly", MiniCatConfig.SESSION_ID_FIELD_NAME,
					request.getSessionId());
			response.getHeader().put("Set-Cookie", cookie);
		}

		StringBuilder responseHeader = new StringBuilder("HTTP/1.1 ").append(httpCode).append(" ").append("\r\n");
		for (String key : response.getHeader().keySet()) {
			responseHeader.append(key).append(": ").append(response.getHeader().get(key)).append("\r\n");
		}
		responseHeader.append("\r\n");
		response.getOutputStream().reset();
		response.getOutputStream().write(responseHeader.toString().getBytes(MiniCatConfig.ENCODE));
		if(!StringUtil.isNullOrEmpty(data)){
			response.getOutputStream().write(data);
		}
		return response.getOutputStream();
	}

	public ByteArrayOutputStream buildResponse() throws IOException {
		return buildResponse(response.getHttpCode(), response.getOutputStream().toByteArray());
	}

}
